﻿using System.Diagnostics.CodeAnalysis;
using System.Windows.Media;

namespace DimensionsHelper.Client.Controls;

public class BorderGridLineRenderer : DrawingVisual
{
    private static void DrawLine(DrawingContext context, Pen? pen,
        double x1, double y1, double x2, double y2)
    {
        Point start = new(x1, y1);
        Point end = new(x2, y2);
        context.DrawLine(pen, start, end);
    }


    internal void DrawLine(IEnumerable<BorderGridLineInfo> ranges)
    {
        using DrawingContext context = RenderOpen();

        foreach (BorderGridLineInfo range in ranges)
        {
            DrawLine(context, range.Pen, range.X1, range.Y1, range.X2, range.Y2);
        }

        context.Close();
    }


    public void DrawLine(Pen? pen, double x1, double y1, double x2, double y2)
    {
        using DrawingContext context = RenderOpen();
        DrawLine(context, pen, x1, y1, x2, y2);
        context.Close();
    }


    public void ClearDrawing(double x, double y, double width, double height)
    {
        using DrawingContext drawingContext = RenderOpen();
        drawingContext.DrawRectangle(Brushes.Red, null, new Rect(x, y, width, height));
        drawingContext.Close();
    }
}


internal struct BorderGridLineInfo : IEquatable<BorderGridLineInfo>
{
    internal BorderGridLineInfo(Pen? pen, double x1, double y1, double x2, double y2)
    {
        Pen = pen;
        X1 = x1;
        Y1 = y1;
        X2 = x2;
        Y2 = y2;
    }


    public Pen? Pen { get; }

    public double X1 { get; set; }

    public double Y1 { get; set; }

    public double X2 { get; set; }

    public double Y2 { get; set; }


    public static BorderGridLineInfo Empty { get; } = new(new Pen(), 0, 0, 0, 0);


    public readonly override int GetHashCode()
    {
        return HashCode.Combine(Pen?.GetHashCode(), X1, Y1, X2, Y2);
    }


    public readonly override bool Equals([NotNullWhen(true)] object? obj)
    {
        if (obj is not BorderGridLineInfo info)
        {
            return false;
        }

        return info.Pen == Pen
               && info.X1 == X1
               && info.Y1 == Y1
               && info.X2 == X2
               && info.Y2 == Y2;
    }


    public static bool operator ==(BorderGridLineInfo left, BorderGridLineInfo right)
    {
        return left.Equals(right);
    }


    public static bool operator !=(BorderGridLineInfo left, BorderGridLineInfo right)
    {
        return !left.Equals(right);
    }

    public readonly bool Equals(BorderGridLineInfo other)
    {
        return Equals(Pen, other.Pen)
               && X1.Equals(other.X1)
               && Y1.Equals(other.Y1)
               && X2.Equals(other.X2)
               && Y2.Equals(other.Y2);
    }
}